<template>
  <ul class="page">
    <li class="page-item" :class="{ disabled: !hasPrev }">
      <button class="prev-button" tabindex="-1" @click="handlePrevClick">上一页</button>
    </li>
    <!-- Show first page -->
    <li class="page-item" v-if="firstPage != null" :class="{ active: page === firstPage }">
      <button @click="handlePageItemClick(firstPage)" :class="{ active: page === firstPage }">
        {{ firstPage + 1 }}
      </button>
    </li>
    <!-- Show middle page -->
    <li class="page-item" v-show="hasMorePrev">
      <span>...</span>
    </li>
    <li class="page-item" v-for="middlePage in middlePages" :key="middlePage" :class="{ active: middlePage === page }">
      <button @click="handlePageItemClick(middlePage)" :class="{ active: middlePage === page }">
        {{ middlePage + 1 }}
      </button>
    </li>

    <li class="page-item" v-show="hasMoreNext">
      <span>...</span>
    </li>
    <!-- Show last page -->
    <li class="page-item" v-if="lastPage" :class="{ active: page === lastPage }">
      <button @click="handlePageItemClick(lastPage)" :class="{ active: page === lastPage }">
        {{ lastPage + 1 }}
      </button>
    </li>

    <li class="page-item" :class="{ disabled: !hasNext }">
      <button class="next-button" @click="handleNextClick">下一页</button>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'Pagination',
  model: {
    prop: 'page',
    event: 'change'
  },
  props: {
    page: {
      type: Number,
      required: false,
      default: 0
    },
    size: {
      type: Number,
      required: false,
      default: 10
    },
    total: {
      type: Number,
      required: false,
      default: 0
    }
  },
  data() {
    return {
      middleSize: 3
    }
  },
  computed: {
    pages() {
      return Math.ceil(this.total / this.size)
    },
    hasNext() {
      return this.page < this.pages - 1
    },
    hasPrev() {
      return this.page > 0
    },
    firstPage() {
      if (this.pages === 0) {
        return null
      }
      return 0
    },
    hasMorePrev() {
      if (this.firstPage === null || this.pages <= this.middleSize + 2) {
        return false
      }
      return this.page >= 2 + this.middleSize / 2
    },
    hasMoreNext() {
      if (this.lastPage === null || this.pages <= this.middleSize + 2) {
        return false
      }
      return this.page < this.lastPage - 1 - this.middleSize / 2
    },
    middlePages() {
      if (this.pages <= 2) {
        return []
      }
      if (this.pages <= 2 + this.middleSize) {
        return this.range(1, this.lastPage)
      }
      const halfMiddleSize = Math.floor(this.middleSize / 2)
      let left = this.page - halfMiddleSize
      let right = this.page + halfMiddleSize
      if (this.page <= this.firstPage + halfMiddleSize + 1) {
        left = this.firstPage + 1
        right = left + this.middleSize - 1
      } else if (this.page >= this.lastPage - halfMiddleSize - 1) {
        right = this.lastPage - 1
        left = right - this.middleSize + 1
      }
      return this.range(left, right + 1)
    },
    lastPage() {
      if (this.pages === 0 || this.pages === 1) {
        return 0
      }
      return this.pages - 1
    }
  },
  methods: {
    handleNextClick() {
      if (this.hasNext) {
        this.$emit('change', this.page + 1)
      }
    },
    handlePrevClick() {
      if (this.hasPrev) {
        this.$emit('change', this.page - 1)
      }
    },
    handlePageItemClick(page) {
      this.$emit('change', page)
    },
    range(left, right) {
      if (left >= right) {
        return []
      }
      const result = []
      for (let i = left; i < right; i++) {
        result.push(i)
      }
      return result
    }
  }
}
</script>

<style lang="scss"></style>
